/* $Header: sig_init.c,v 2.2 01/10/02 10:33:04 przybyls Exp $ */

/***********************************************************************/
/*                                                                     */
/*                  Copyright Hewlett-Packard Co. 1991                 */
/*                                                                     */
/***********************************************************************/

/***********************************************************************/
/* MODULE NAME: sig_init.c                                             */
/* ============                                                        */
/*                                                                     */
/* Author:  Lesley Freed                                               */
/*                                                                     */
/* MODULE PURPOSE:  To initialize the Signal Path.                     */
/*                                                                     */
/*                                                                     */
/***********************************************************************/

/*****************************/
/*   GLOBAL INCLUDE FILES    */
/*****************************/

#include <typedefs.h>
#include <p_wkfile.h>
#include <wkfile.h>
#include <ramps.h>
#include <zone_config.h>
#include <zone_status.h>
#include <status.h>
#include <error.h>
#include <sig_types.h>
#include <sigpath.h>
#include <sig_ui.h>
#include <dig_path.h>
#include <i_op.h>

#include <clock_ui.h>

/*****************************/
/*   LOCAL INCLUDE FILES     */
/*****************************/


/*****************************/
/*   GLOBAL VARIABLES        */
/*****************************/

/*****************************/
/*   EXTERNAL VARIABLES      */
/*****************************/


/*****************************/
/*   LOCAL DEFINES           */
/*****************************/





/*****************************/
/*   IMPLEMENT SECTION       */
/*****************************/

/***********************************************************************/
/* FUNCTION:  SetSigPathDefaultSetpts                                  */
/* ========                                                            */
/*                                                                     */
/* PURPOSE: To initialize the default setpoints for the workfile       */
/*          for the Signal Path.                                       */
/*                                                                     */
/* LIMITATIONS: Does not check to see if there is an existing          */
/*              workfile.                                              */
/*                                                                     */
/***********************************************************************/

void SetSignalDefaultSetpts( pSIG_SETPTS psetpts )
{
   psetpts->rate = (BIT8)RATE_20HZ;       /* set data rate to 20 Hz     */
   psetpts->bunch_count = 1;              /* default bunch count = 1    */
   psetpts->DAC_rate = DAC_RATE_3HZ;      /* apply 3 Hz filter to DAC   */
   psetpts->range = 0;                    /* default to 1 mV output for */
                                          /* 240 counts signal value    */
   psetpts->attn = 0;                     /* default to no attn         */
   psetpts->zero_attn_on_off = ZERO_ON_MASK | ATTN_ON_MASK;
   psetpts->plot = 0;                     /* default addr               */
   psetpts->size = (BIT8)NOT_PLOT_SIGNAL; /* default to det type sig    */

}

SIG_TYPE GetDefaultSignal( U_INT8 chan )
{
   DET_TYPE   deta;             /* type of detector for front detector        */
   DET_TYPE   detb;             /* type of detector for back detector         */

   deta = DetectorA_Config.type;
   detb = DetectorB_Config.type;

   /* Get the signal type based upon what is installed. */

   if (( deta == NO_DET ) && ( detb == NO_DET ))
   {
      /* We have no detectors.  We must default to test plot. */

      return TEST_PLOT_SIGNAL;

   }

   if (( deta == NO_DET ) && ( detb != NO_DET ))
   {
      /* We have a detector board in the back detector slot only so we will   */
      /* default to that signal.                                              */

      return DETB_SIGNAL;     /* set signal to back det */

   }

   if (( deta != NO_DET ) && ( detb == NO_DET ))
   {
      /* We have a detector board in the front detector slot only so we will  */
      /* default to that signal.                                              */
      return DETA_SIGNAL;     /* set signal to front det */

   }

   if (( deta != NO_DET ) && ( detb != NO_DET ))
   {
      /* We have detector boards in the front and back detector slots. */

      if ( chan == SIGNAL1 ) return DETA_SIGNAL;  /* set signal to front det */
      return DETB_SIGNAL;                         /* set signal to back det  */

   }

   /* to satisfy Flexelint */ return TEST_PLOT_SIGNAL;

}


/***********************************************************************/
/* FUNCTION:  UpdateSigPathStatus                                      */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:  To transfer Active_Wkfile setpoints into SigPath working  */
/*           setpoints.  This function -also- assigns the SIG_TABLE    */
/*           structure's pointers to the active workfile setpts.       */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/***********************************************************************/

void UpdateSignalStatus( pSIG_TABLE psignal )
{
   SIG_TYPE type;

   INTERRUPTS_OFF

      psignal->plot             = psignal->active_wkfile->plot;
      psignal->plot_size        = (DATA_SIZE)psignal->active_wkfile->size;
      psignal->zero             = psignal->active_wkfile->zero;
      psignal->range            = psignal->active_wkfile->range;
      psignal->attn             = psignal->active_wkfile->attn;
      psignal->zero_attn_on_off = psignal->active_wkfile->zero_attn_on_off &  RESUMEX_FRZ_OFF_MSK;
                                                  /* reset the freeze/resume RTT flags also !      */

   INTERRUPTS_ON

   type = (SIG_TYPE)psignal->active_wkfile->signal;

   if ( type == MEMORY_LOCATION )
   {
      (void)SetSignalMemLoc (psignal,
                             (DATA_SIZE)psignal->active_wkfile->size,
                             psignal->active_wkfile->plot);
   }
   else
   {
      (void)SetSignalTypeMain( psignal,(SIG_TYPE)psignal->active_wkfile->signal,
                               FALSE );
   }

   /* set the runtime stored signal value to zero */
   psignal->stored_value = 0;

}

void UpdateSigPathStatus( void )
{
        /* Initialize the working setpoints */
        UpdateSignalStatus( &Signal1 );

        /* Initialize the working setpoints */
        UpdateSignalStatus( &Signal2 );

}


/***********************************************************************/
/* FUNCTION: InitializeSigPath                                         */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:  To initialize the signal path variables.                  */
/*                                                                     */
/* CALLS:    InitializeDspOut                                          */
/*                                                                     */
/* LIMITATIONS:  This function MUST be called before                   */
/*               UpdateSigPathStatus which relies on information setup */
/*               in InitScc.                                           */
/*                                                                     */
/***********************************************************************/

void InitSignal( pSIG_TABLE psignal )
{
   U_INT8 i;

   /* Set the signal run state to idle */
   psignal->run_state = NOT_IN_RUN;

   /* Initialize the filters */

   psignal->bunch_sum.lo = 0;
   psignal->bunch_sum.hi = 0;
   psignal->filt_bunch_sum.hi = 0;
   psignal->filt_bunch_sum.lo = 0;
   for (i=0; i<3; i++)
   {
      psignal->bunch_table[i].hi = 0;
      psignal->bunch_table[i].lo = 0;
   }
   psignal->bunch_reset = TRUE;
   psignal->bunch_out.output.hi_long = 0;
   psignal->bunch_out.output.lo_word = 0;
   psignal->bunch_out.remainder = 0;

   /* Init signal display filter */
   psignal->filt_sum.lo = 0;
   psignal->filt_sum.hi = 0;
   psignal->filt_out.output    = 0;
   psignal->filt_out.remainder = 0;
   psignal->ptr_filt = ARRAY_SIZE_SIG_DISP-1;
   for (i=0; i<ARRAY_SIZE_SIG_DISP; i++)
   {
      psignal->filt_table [i] = 0;
   }

   /* Init scc detector data filters */
   Deta_Filt.pfilt_table = (INT32 *)Deta_Filt_Table;
   Detb_Filt.pfilt_table = (INT32 *)Detb_Filt_Table;
   Sig1_Filt.pfilt_table = (INT32 *)Sig1_Filt_Table;
   Sig2_Filt.pfilt_table = (INT32 *)Sig2_Filt_Table;
   Deta_Filt.size  = ARRAY_SIZE_SCC_DET;
   Detb_Filt.size  = ARRAY_SIZE_SCC_DET;
   Sig1_Filt.size  = ARRAY_SIZE_SIG_DISP;
   Sig2_Filt.size  = ARRAY_SIZE_SIG_DISP;

   psignal->filter_sum_3_DAC = 0;
   psignal->ptr_filter_3_DAC  = DAC_ARRAY_SIZE_3HZ-1;
   for (i=0; i<DAC_ARRAY_SIZE_3HZ; i++)
   {
      psignal->filter_3_DAC [i] = 0;
   }

}

void InitializeSigPath(void)
{

/* SIGNAL 1 */
        /* Set up the variable chan to indicate which channel # we are        */
        /* processing.  This is used to invoke CompressAndStore and pass the  */
        /* channel #.                                                         */

        Signal1.chan = SIGNAL1;

        /* Assign ptrs to workfile setpts and DSP input data */
        Signal1.active_wkfile = &Active_Wkfile.signal1;

        Signal1.dsp_data = &Dsp_In.signal1_data;


/* SIGNAL 2 */

        /* Set up the variable chan to indicate which channel # we are        */
        /* processing.  This is used to invoke CompressAndStore and pass the  */
        /* channel #.                                                         */

        Signal2.chan = SIGNAL2;

        /* Assign ptrs to workfile setpts and DSP input data */
        Signal2.active_wkfile = &Active_Wkfile.signal2;

        Signal2.dsp_data = &Dsp_In.signal2_data;


/* SIGNAL P */

        /* Set up the variable chan to indicate which channel # we are        */
        /* processing.  This is used to invoke CompressAndStore and pass the  */
        /* channel #.                                                         */

        SignalP.chan = SIGNALP;

        /* Assign ptrs to workfile setpts and DSP input data */
        SignalP.active_wkfile = &Active_Wkfile.signalP;


   InitializeDspOut();

   InitializeScc();

   /* Set the execution state of the Signal Path to idle. */
   Analog_Err_Count = 0;
   Sig_State = SIG_IDLE;


   InitSignal( &Signal1 );
   InitSignal( &Signal2 );
   InitSignal( &SignalP );

}



/***********************************************************************/
/* FUNCTION: InitializeDspOut                                          */
/* ========                                                            */
/*                                                                     */
/* PURPOSE: To set the default setpoints for output to the Detector    */
/*          DSP.                                                       */
/*                                                                     */
/***********************************************************************/

void InitializeDspOut( void )
{

/* Note:  We will just set the data rate and type here, the rest of the dsp   */
/*        data structure will be initialized in InitializeDetectors and       */
/*        MeasureDetectorOffset.                                              */

/* Set up the Defaults for the data output to the signal DSP, Dsp_Out         */
/* Note:  The signal definition, sig1_def and sig2_def fields will be         */
/*        initialized here to the detector definition.  They will be reset    */
/*        by calling SetSignalType within InitializeSigPath. This is done     */
/*        because we need to do some decoding to remove any possible column   */
/*        compensation information from the signal definition since the       */
/*        signal DSP only recognizes "vanilla" type signals. If the signal is */
/*        set to an alternate type signal then we will not be resetting the   */
/*        DSP signal type so it will remain the default set here.             */

   Dsp_Out.sig1_rate = (U_INT16)RATE_TABLE[Active_Wkfile.signal1.rate].rate;
   Dsp_Out.sig2_rate = (U_INT16)RATE_TABLE[Active_Wkfile.signal2.rate].rate;

   Dsp_Out.sig1_def  = (U_INT16)DETA_SIGNAL;
   Dsp_Out.sig2_def  = (U_INT16)DETB_SIGNAL;
}



void InitializePwrFailSigPath( void )
{
   POSITION ccomp1_position;
   POSITION ccomp2_position;

   /* Set up initial values for the stored scc profiles */
   Ccomp1_Data.data_valid_flag = NO_DATA;
   Ccomp2_Data.data_valid_flag = NO_DATA;
   InitializeDateTime( &(Ccomp1_Data.datetime) );
   InitializeDateTime( &(Ccomp2_Data.datetime) );

   /* Even though we have no data, initialize the detector position and type  */
   /* to the Active_Wkfile setpt.                                             */
   ccomp1_position = Active_Wkfile.col_comp1_det;
   ccomp2_position = Active_Wkfile.col_comp2_det;
   Ccomp1_Data.det_data_stored = ccomp1_position;
   Ccomp2_Data.det_data_stored = ccomp2_position;

   /* We do not have a profile, so default to no detector */
   Ccomp1_Data.det_type = NO_DET;
   Ccomp2_Data.det_type = NO_DET;
}

void SetSigTypePFDefaultSetpt( pSIG_TABLE psignal )
{
   (void) SetSignalType( psignal, GetDefaultSignal( psignal == pSIGNAL1 ? SIGNAL1 :
                                           ( psignal == pSIGNAL2 ? SIGNAL2 : SIGNALP ) ) );
}

void SetColCompPFDefaultSetpts( POSITION *pcomp_position )
{
   switch( GetSignalType((pcomp_position == &Active_Wkfile.col_comp1_det) ? pSIGNAL1:pSIGNAL2))
   {
      case DETA_SIGNAL:       *pcomp_position = FRONT;
                              break;
      case DETB_SIGNAL:       *pcomp_position = BACK;
                              break;
      default:
      case TEST_PLOT_SIGNAL:  *pcomp_position = NULL_POSITION;
                              break;
   }
}

/***********************************************************************/
/* FUNCTION:  ResolveSigPathPFDefaultSetpts                            */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/* CALLS:                                                              */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/***********************************************************************/

void ResolveSignalPowerOnSetpt( pSIG_TABLE psignal )
{
   if ( CheckSignalType( (SIG_TYPE)GetSignalType( psignal ) ) != OK )
   {
      /* Default to power-fail value */
      SetSigTypePFDefaultSetpt( psignal );
   }
}

void ResolveColCompPowerOnSetpts( pCCOMP_TABLE pccomp )
{
   if ( CheckSccSignalType( pccomp, GetSccSignalType( pccomp ) ) )
   {
      /* Default to power-fail value */
      SetColCompPFDefaultSetpts( ( pccomp == pCCOMP1 ) ?  \
                                 &Active_Wkfile.col_comp1_det : &Active_Wkfile.col_comp2_det  );
   }
}

void ResolveSigPathPowerOnSetpts( void )
{
   ResolveSignalPowerOnSetpt( pSIGNAL1 );
   ResolveSignalPowerOnSetpt( pSIGNAL2 );
   ResolveSignalPowerOnSetpt( pSIGNALP );
   ResolveColCompPowerOnSetpts( pCCOMP1 );
   ResolveColCompPowerOnSetpts( pCCOMP2 );
}


/***********************************************************************/
/* FUNCTION:  SetSigPathDefaultSetpts                                  */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:  To set ALL of the signal path setpts to their default     */
/*           values.                                                   */
/*                                                                     */
/* RETURNED VALUE:  none                                               */
/*                                                                     */
/* GLOBALS USED:  Active_Wkfile                                        */
/*                                                                     */
/* CALLS:  SetSigTypePFDefaultSetpts, SetColCompPFDefaultSetpts,       */
/*         SetSignalDefaultSetpts                                      */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/***********************************************************************/

void SetSigPathDefaultSetpts( void )
{
   SetSigTypePFDefaultSetpt( pSIGNAL1 );
   SetSigTypePFDefaultSetpt( pSIGNAL2 );
   SetSigTypePFDefaultSetpt( pSIGNALP );

   /* Now default the column compensation position setpt based upon default   */
   /* signal type.                                                            */
   SetColCompPFDefaultSetpts( &Active_Wkfile.col_comp1_det );
   SetColCompPFDefaultSetpts( &Active_Wkfile.col_comp2_det );

   SetSignalDefaultSetpts( &Active_Wkfile.signal1 );
   SetSignalDefaultSetpts( &Active_Wkfile.signal2 );
   SetSignalDefaultSetpts( &Active_Wkfile.signalP );

}
